Python でアプリ開発できる Flet を触ってみた
こんにちは、森田です。
最近周りの人から Python でアプリ開発のできる Flet について教えてもらい、面白そうなのでチュートリアルをやってみました。
よかったら参考にしてみてください。
Flet とは
Flet は、フロントエンド開発の経験がなくても、簡単に Web、デスクトップ、モバイル アプリケーションを開発できるフレームワークです。
開発はPythonで行うことができ、内部的には、Flutter を利用しているようです。
標準でウィジェットが用意されているため、フロントの開発を行うことなく、少ない労力で、アプリとして動作させることができます。
Python で複雑すぎないアプリを作りたい場合にピッタリのフレームワークとなります。
やってみた
本記事では、チュートリアルに従って、電卓アプリを作ってみます。
なお、本記事では、Mac Python 3.8.13にて行います。
ライブラリのインストール
まずは、Fletのインストールを行います。以下のようにpipを使ってインストールを行います。
pip install flet
ボタンの作成
電卓のボタンを作成していきます。
ElevatedButtonを利用することで、作成可能です。
以下のコードでは、電卓の各ボタンを作成しております。
text引数に指定した文字列がボタン内に表示されます。
import flet as ft def main(page: ft.Page): page.title = "Calc App" result = ft.Text(value="0") page.add( result, ft.ElevatedButton(text="AC"), ft.ElevatedButton(text="+/-"), ft.ElevatedButton(text="%"), ft.ElevatedButton(text="/"), ft.ElevatedButton(text="7"), ft.ElevatedButton(text="8"), ft.ElevatedButton(text="9"), ft.ElevatedButton(text="*"), ft.ElevatedButton(text="4"), ft.ElevatedButton(text="5"), ft.ElevatedButton(text="6"), ft.ElevatedButton(text="-"), ft.ElevatedButton(text="1"), ft.ElevatedButton(text="2"), ft.ElevatedButton(text="3"), ft.ElevatedButton(text="+"), ft.ElevatedButton(text="0"), ft.ElevatedButton(text="."), ft.ElevatedButton(text="="), ) ft.app(target=main)
実行結果
通常のPythonスクリプトのように実行すると、ウィンドウが開き、以下のようにボタンが表示されます。
python button_test.py
レイアウト調整
作成したボタンを電卓のようなレイアウトに変更します。
ft.Rowを使って行ごとの要素を並べていきます。
import flet as ft def main(page: ft.Page): page.title = "Calc App" result = ft.Text(value="0") page.add( ft.Row(controls=[result]), ft.Row( controls=[ ft.ElevatedButton(text="AC"), ft.ElevatedButton(text="+/-"), ft.ElevatedButton(text="%"), ft.ElevatedButton(text="/"), ] ), ft.Row( controls=[ ft.ElevatedButton(text="7"), ft.ElevatedButton(text="8"), ft.ElevatedButton(text="9"), ft.ElevatedButton(text="*"), ] ), ft.Row( controls=[ ft.ElevatedButton(text="4"), ft.ElevatedButton(text="5"), ft.ElevatedButton(text="6"), ft.ElevatedButton(text="-"), ] ), ft.Row( controls=[ ft.ElevatedButton(text="1"), ft.ElevatedButton(text="2"), ft.ElevatedButton(text="3"), ft.ElevatedButton(text="+"), ] ), ft.Row( controls=[ ft.ElevatedButton(text="0"), ft.ElevatedButton(text="."), ft.ElevatedButton(text="="), ] ), ) ft.app(target=main)
実行結果
デザインのカスタマイズ
ボタンの色変更などを行います。
bgcolorやcolorで色変更を行います。
import flet from flet import ( Column, Container, ElevatedButton, Page, Row, Text, border_radius, colors, ) def main(page: Page): page.title = "Calc App" result = Text(value="0", color=colors.WHITE, size=20) page.add( Container( width=300, bgcolor=colors.BLACK, border_radius=border_radius.all(20), padding=20, content=Column( controls=[ Row(controls=[result], alignment="end"), Row( controls=[ ElevatedButton( text="AC", bgcolor=colors.BLUE_GREY_100, color=colors.BLACK, expand=1, ), ElevatedButton( text="+/-", bgcolor=colors.BLUE_GREY_100, color=colors.BLACK, expand=1, ), ElevatedButton( text="%", bgcolor=colors.BLUE_GREY_100, color=colors.BLACK, expand=1, ), ElevatedButton( text="/", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, ), ] ), Row( controls=[ ElevatedButton( text="7", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="8", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="9", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="*", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, ), ] ), Row( controls=[ ElevatedButton( text="4", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="5", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="6", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="-", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, ), ] ), Row( controls=[ ElevatedButton( text="1", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="2", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="3", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="+", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, ), ] ), Row( controls=[ ElevatedButton( text="0", bgcolor=colors.WHITE24, color=colors.WHITE, expand=2, ), ElevatedButton( text=".", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, ), ElevatedButton( text="=", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, ), ] ), ] ), ) ) flet.app(target=main)
実行結果
以下のように良い感じに電卓アプリケーションが表示されます。
ボタン押下時のイベント処理
見た目の作成は完了しましたので、再度に電卓として利用できるように、計算の処理を追加します。
ft.ElevatedButtonでは、on_clickにボタンを押下時に実行する関数を指定することができます。
import flet from flet import ( Column, Container, ElevatedButton, Page, Row, Text, UserControl, border_radius, colors, ) class CalculatorApp(UserControl): def build(self): self.reset() self.result = Text(value="0", color=colors.WHITE, size=20) # application's root control (i.e. "view") containing all other controls return Container( width=300, bgcolor=colors.BLACK, border_radius=border_radius.all(20), padding=20, content=Column( controls=[ Row(controls=[self.result], alignment="end"), Row( controls=[ ElevatedButton( text="AC", bgcolor=colors.BLUE_GREY_100, color=colors.BLACK, expand=1, on_click=self.button_clicked, data="AC", ), ElevatedButton( text="+/-", bgcolor=colors.BLUE_GREY_100, color=colors.BLACK, expand=1, on_click=self.button_clicked, data="+/-", ), ElevatedButton( text="%", bgcolor=colors.BLUE_GREY_100, color=colors.BLACK, expand=1, on_click=self.button_clicked, data="%", ), ElevatedButton( text="/", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="/", ), ], ), Row( controls=[ ElevatedButton( text="7", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="7", ), ElevatedButton( text="8", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="8", ), ElevatedButton( text="9", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="9", ), ElevatedButton( text="*", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="*", ), ] ), Row( controls=[ ElevatedButton( text="4", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="4", ), ElevatedButton( text="5", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="5", ), ElevatedButton( text="6", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="6", ), ElevatedButton( text="-", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="-", ), ] ), Row( controls=[ ElevatedButton( text="1", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="1", ), ElevatedButton( text="2", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="2", ), ElevatedButton( text="3", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="3", ), ElevatedButton( text="+", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="+", ), ] ), Row( controls=[ ElevatedButton( text="0", bgcolor=colors.WHITE24, color=colors.WHITE, expand=2, on_click=self.button_clicked, data="0", ), ElevatedButton( text=".", bgcolor=colors.WHITE24, color=colors.WHITE, expand=1, on_click=self.button_clicked, data=".", ), ElevatedButton( text="=", bgcolor=colors.ORANGE, color=colors.WHITE, expand=1, on_click=self.button_clicked, data="=", ), ] ), ], ), ) def button_clicked(self, e): data = e.control.data if self.result.value == "Error" or data == "AC": self.result.value = "0" self.reset() elif data in ("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."): if self.result.value == "0" or self.new_operand == True: self.result.value = data self.new_operand = False else: self.result.value = self.result.value + data elif data in ("+", "-", "*", "/"): self.result.value = self.calculate( self.operand1, float(self.result.value), self.operator ) self.operator = data if self.result.value == "Error": self.operand1 = "0" else: self.operand1 = float(self.result.value) self.new_operand = True elif data in ("="): self.result.value = self.calculate( self.operand1, float(self.result.value), self.operator ) self.reset() elif data in ("%"): self.result.value = float(self.result.value) / 100 self.reset() elif data in ("+/-"): if float(self.result.value) > 0: self.result.value = "-" + str(self.result.value) elif float(self.result.value) < 0: self.result.value = str( self.format_number(abs(float(self.result.value))) ) self.update() def format_number(self, num): if num % 1 == 0: return int(num) else: return num def calculate(self, operand1, operand2, operator): if operator == "+": return self.format_number(operand1 + operand2) elif operator == "-": return self.format_number(operand1 - operand2) elif operator == "*": return self.format_number(operand1 * operand2) elif operator == "/": if operand2 == 0: return "Error" else: return self.format_number(operand1 / operand2) def reset(self): self.operator = "+" self.operand1 = 0 self.new_operand = True def main(page: Page): page.title = "Calc App" # create application instance calc = CalculatorApp() # add application's root control to the page page.add(calc) flet.app(target=main)
実行結果
実際に実行すると、以下のようにボタン押下時に計算を行い、計算結果の表示ができるようになります。
さいごに
今回は、Fletを使ってアプリ開発を行ってみましたが、非常に簡単に作成できます。
ウィジェットも豊富に用意されているため、素早くアプリ開発を行いたい場合には、とても便利です。
今までPythonを使ったことのある方は、すぐに活用することができますので、ぜひお試しください。